package org.hackystat.projecttrajectory;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hackystat.project.ProjectException;
import org.hackystat.utilities.logger.HackystatLogger;

/**
 * ProjectTrajectoryProperties wraps the Sensorbase and DailyProjectData
 * properties.
 * 
 * @author Cam Moore
 * 
 */
public final class ProjectTrajectoryProperties {

  /** Hackystat sensorbase host such as
   * http://localhost:9876/sensorbase. */
  public static final String SENSORBASE_HOST_KEY = "projecttrajectory.sensorbase.host";
  /** User's email. */
  public static final String EMAIL_KEY = "projecttrajectory.email";
  /** User's password. */
  public static final String PASSWORD_KEY = "projecttrajectory.password";
  /**
   * The daily project data host, such as
   * http://localhost:9877/dailyprojectdata
   */
  public static final String DPD_HOST_KEY = "projecttrajectory.dpd.host";
  /** Test Hackystat sensorbase host. */
  public static final String TEST_SENSORBASE_HOST_KEY = "projecttrajectory.test.sensorbase.host";
  /** Test User's email. */
  public static final String TEST_EMAIL_KEY = "projecttrajectory.test.email";
  /** Test User's password. */
  public static final String TEST_PASSWORD_KEY = "projecttrajectory.test.password";
  /** Test daily project data host */
  public static final String TEST_DPD_HOST_KEY = "projecttrajectory.test.dpd.host";

  private Properties properties;

  private static ProjectTrajectoryProperties instance;
  private Logger logger;
  private Level debugLevel = Level.FINEST;

  /**
   * Constructs a ProjectTrajectoryProperties.
   * 
   * @throws ProjectException if the sensorbase and dailyprojectdata's
   *           sensorbase are not the same.
   */
  private ProjectTrajectoryProperties() throws ProjectException {
    this(System.getProperty("user.home"));
  }

  /**
   * Constructs a ProjectTrajectoryProperties.
   * 
   * @param userHome a String, the directory where the .hackystat folder is.
   * @throws ProjectException if the sensorbase and dailyprojectdata's
   *           sensorbase are not the same.
   */
  private ProjectTrajectoryProperties(String userHome) throws ProjectException {
    logger = HackystatLogger.getLogger("org.hackystat.project.ProjectTrajectoryProperties");
    initializeProperties(userHome);
  }

  /**
   * @return The singleton ProjectTrajectoryProperties instance.
   * @throws ProjectException if the sensorbase and dailyprojectdata's
   *           sensorbase are not the same.
   */
  public static synchronized ProjectTrajectoryProperties getInstance() throws ProjectException {
    if (instance == null) {
      instance = new ProjectTrajectoryProperties();
    }
    return instance;
  }

  /**
   * @param userHome a String, the directory holding the .hackystat folder.
   * @return The singleton ProjectTrajectoryProperties instance.
   * @throws ProjectException if the sensorbase and dailyprojectdata's
   *           sensorbase are not the same.
   */
  public static synchronized ProjectTrajectoryProperties getInstance(String userHome)
      throws ProjectException {
    if (instance == null) {
      instance = new ProjectTrajectoryProperties(userHome);
    }
    return instance;
  }

  /**
   * @return The sensorbase URI as a String.
   */
  public String getSensorbase() {
    return properties.getProperty(SENSORBASE_HOST_KEY);
  }

  /**
   * @return The user's email as a String.
   */
  public String getEmail() {
    return properties.getProperty(EMAIL_KEY);
  }

  /**
   * @return The user's password as a String.
   */
  public String getPassword() {
    return properties.getProperty(PASSWORD_KEY);
  }

  /**
   * @return The dailyprojectdata URI as a String.
   */
  public String getDailyProjectData() {
    return properties.getProperty(DPD_HOST_KEY);
  }

  /**
   * Sets the properties to the testing version.
   */
  public void setTestProperties() {
    this.properties.setProperty(SENSORBASE_HOST_KEY, this.properties
        .getProperty(TEST_SENSORBASE_HOST_KEY));
    this.properties.setProperty(EMAIL_KEY, this.properties.getProperty(TEST_EMAIL_KEY));
    this.properties.setProperty(PASSWORD_KEY, this.properties.getProperty(TEST_PASSWORD_KEY));
    this.properties.setProperty(DPD_HOST_KEY, this.properties
        .getProperty(TEST_DPD_HOST_KEY));
  }

  /**
   * Initializes the properties from the v8.sensor.properties and
   * dailyprojectdata.properties files.
   * 
   * @param userHome a String, the directory holding the .hackystat folder.
   */
  public void initializeProperties(String userHome) {
    String hackyHome = userHome + File.separator + ".hackystat";
    String ptPropFile = hackyHome + File.separator + "projecttrajectory" + File.separator
        + "projecttrajectory.properties";

    this.properties = new Properties();

    String defaultAdmin = "admin@hackystat.org";
    // set the default values
    this.properties.setProperty(SENSORBASE_HOST_KEY, "http://localhost:9876/sensorbase");
    this.properties.setProperty(EMAIL_KEY, defaultAdmin);
    this.properties.setProperty(PASSWORD_KEY, defaultAdmin);
    this.properties.setProperty(DPD_HOST_KEY, "http://localhost:9877/dailyprojectdata");
    this.properties.setProperty(TEST_SENSORBASE_HOST_KEY, "http://localhost:9976/sensorbase");
    this.properties.setProperty(TEST_EMAIL_KEY, defaultAdmin);
    this.properties.setProperty(TEST_PASSWORD_KEY, defaultAdmin);
    this.properties.setProperty(TEST_DPD_HOST_KEY, "http://localhost:9977/dailyprojectdata");

    FileInputStream stream = null;
    try {
      stream = new FileInputStream(ptPropFile);
      properties.load(stream);
      logger.log(debugLevel, "Loading SensorBase properties from: " + ptPropFile);
    } catch (IOException e) {
      logger.warning(ptPropFile + " not found. Using default project trajectory properties.");
    } finally {
      if (stream != null) {
        try {
          stream.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }

}
